package com.google.common.collect;

import com.google.common.base.Function;
import com.google.common.cache.*;

import java.util.concurrent.TimeUnit;

public class OtterMigrateMap {


    public static <K, V> LoadingCache<K, V> makeSoftValueComputingMap(Function<K, V> computingFunction) {
        return CacheBuilder.newBuilder().softValues().build(CacheLoader.from(computingFunction));
    }

    public static <K, V> LoadingCache<K, V> makeComputingMap(Function<K,V> computingFunction) {
        return CacheBuilder.newBuilder().build(CacheLoader.from(computingFunction));
    }

    public static <K, V> LoadingCache<K, V> makeSoftValueComputingMapWithTimeout(Function<K,  V> computingFunction,
                                                                                  long timeout, TimeUnit timeUnit) {
        return CacheBuilder.newBuilder()
                .expireAfterAccess(timeout, timeUnit)
                .softValues().build(CacheLoader.from(computingFunction));
    }


    public static <K, V> Cache<K, V> makeSoftValueMapWithTimeout(long timeout, TimeUnit timeUnit) {
        return CacheBuilder.newBuilder()
                .expireAfterAccess(timeout, timeUnit)
                .softValues().build();
    }

    public static <K, V> LoadingCache<K,V> makeSoftValueComputingMapWithRemoveListener(Function<K,V> computingFunction,
                                                                                                   final OtterRemovalListener<K, V> listener) {
        return CacheBuilder.newBuilder().softValues()
                .removalListener((RemovalListener<? super K, ? super V>) n -> {
                    if (n.getKey() == null || n.getValue() == null) {
                        return;
                    }
                    listener.onRemoval( n.getKey(),  n.getValue());
                }).build(CacheLoader.from(computingFunction));
    }

    public interface OtterRemovalListener<K, V> {

        void onRemoval(K key, V value);
    }
}
